<?php

namespace app\yy\admin;

use app\common\controller\Common;
use app\yy\model\Images as ImgModel;
use app\yy\model\Website as WebModel;
use app\yy\model\Domain as DoModel;
use app\yy\model\Archive as ArchiveModel;
use app\admin\model\Attachment as AttachModel;
use app\yy\services\Currency;
use app\yy\services\EasyShop;
use app\yy\services\IpInfo;
use app\yy\services\Opencart;
use app\yy\services\Wordpress;
use OSS\Core\OssException;
use OSS\OssClient;
use think\Db;
use think\Exception;

class Task extends Common
{
    public $web_url = '/yy_image.php';
    public $oss_url = 'https://images.yiyangssl.com';

    /**
     * YY 网站同步
     * @return void
     */
    public function async($id = '')
    {
        if (!config('yy_domain_task')) {
            die('后台YY网站迁移任务未开启，不执行');
        }
        set_time_limit(0);
        ini_set('memory_limit', '4000M');
        if ($id) {
            $info = WebModel::where('id', $id)->order('id')->find();
        } else {
            if (WebModel::where('status', 2)->order('id')->find()) {
                die('网站迁移中');
            }
            $info = WebModel::where('status', 1)->order('id')->find();
            if (!$info) {
                echo '无网站可迁移';
                die;
            }
        }

        try {
            WebModel::where('id', $info['id'])->update(['status' => 2, 'process_id' => getmypid(), 'start_time' => date('Y-m-d H:i:s')]);
            $dbstr = $this->checkDb($info);
            // 读取文件
            $file = AttachModel::where('id', $info['atta_id'])->find();
            [$category, $options, $products] = $this->readXlsx($file['path']);
            WebModel::where('id', $info['id'])->update(['remark' => '文件已读取：' . date('Y-m-d H:i:s')]);
            if ($id != 175) {
                // 图片
                if ($info['type'] != 2) {
                    $this->images($products, $info);
                    WebModel::where('id', $info['id'])->update(['remark' => '图片已导入：' . date('Y-m-d H:i:s')]);
                } else {
                    $this->wp_images($products, $info);
                    WebModel::where('id', $info['id'])->update(['remark' => '图片已导入：' . date('Y-m-d H:i:s')]);
                }
            }

            // die('先处理图片');

            if ($info['type'] == 0) {
                $this->yyToEasyShop($info, $dbstr, $category, $options, $products);
            } elseif ($info['type'] == 2) {
                // (new Wordpress())->yyToWordpress($info, $category, $options, $products);
                $this->yyToWordpress($info, $category, $options, $products);
            } else {
                (new Opencart())->yyToOpenCart($info, $dbstr, $category, $options, $products);
            }

        } catch (\ErrorException $e) {
            WebModel::where('id', $info['id'])->update(['status' => 3, 'remark' => '网站迁移失败1', 'end_time' => date('Y-m-d H:i:s')]);
            echo '网站迁移失败1';
            die;
        }
        die;

    }

    /**
     * 验证数据库信息
     * @param $info
     * @return string|void
     */
    public function checkDb($info)
    {
        $archive = ArchiveModel::find($info['archive_id']);
        $dbstr = "mysql://{$archive['db_username']}:{$archive['db_password']}@{$archive['db_hostname']}:3306/{$info['db_database']}";
        try {
            // 尝试建立数据库连接
            Db::connect($dbstr)->query('SELECT 1');
        } catch (\PDOException $e) {
            WebModel::where('id', $info['id'])->update(['status' => 3, 'remark' => '网站数据库连接失败' . $e->getMessage(), 'end_time' => date('Y-m-d H:i:s')]);
            die('网站数据库连接失败');
        }
        return $dbstr;
    }

    public function yyToEasyShop($info, $dbstr, $category, $options, $products)
    {
        // 商品分类
        try {
            $category = $this->category($category, $dbstr);
        } catch (Exception $e) {
            WebModel::where('id', $info['id'])->update(['status' => 3, 'remark' => '商品分类迁移报错' . $e->getMessage(), 'end_time' => date('Y-m-d H:i:s')]);
            echo '商品分类迁移失败';
            die;
        }
        if (!$category) {
            WebModel::where('id', $info['id'])->update(['status' => 3, 'remark' => '商品分类迁移失败', 'end_time' => date('Y-m-d H:i:s')]);
            echo '商品分类迁移失败';
            die;
        }
        WebModel::where('id', $info['id'])->update(['remark' => '商品分类已迁移：' . date('Y-m-d H:i:s')]);
        $category = array_column($category, 'category_id', 'sku');

        // 选项
        try {
            [$db_option_name_list, $db_option_name_value] = $this->option($dbstr, $options);
        } catch (Exception $e) {
            WebModel::where('id', $info['id'])->update(['status' => 3, 'remark' => '商品选项迁移报错' . $e->getMessage(), 'end_time' => date('Y-m-d H:i:s')]);
            echo '商品选项迁移报错';
            die;
        }
        WebModel::where('id', $info['id'])->update(['remark' => '商品选项已迁移：' . date('Y-m-d H:i:s')]);

        // 商品信息
        try {
            $product = $this->createProducts($products, $dbstr, $category, $db_option_name_list, $db_option_name_value, $info);
        } catch (Exception $e) {
            WebModel::where('id', $info['id'])->update(['status' => 3, 'remark' => '商品迁移报错' . $e->getMessage(), 'end_time' => date('Y-m-d H:i:s')]);
            echo '商品迁移报错';
            die;
        }
        if (!$product) {
            WebModel::where('id', $info['id'])->update(['status' => 3, 'remark' => '商品迁移失败', 'end_time' => date('Y-m-d H:i:s')]);
            echo '商品迁移失败';
            die;
        }
        WebModel::where('id', $info['id'])->update(['status' => 4, 'image_status' => 1, 'remark' => '迁移成功', 'end_time' => date('Y-m-d H:i:s')]);
        echo '迁移成功';
        die;
    }

    function multiCurlPost($post_data_array)
    {
        // 初始化 cURL 批处理句柄
        $mh = curl_multi_init();

        // 初始化 cURL 句柄数组
        $ch_array = array();

        foreach ($post_data_array as $post_data) {
            $url = $post_data['url'];
            $data = $post_data['data'];

            // 初始化 cURL 句柄
            $ch = curl_init();

            // 设置 cURL 选项
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

            // 将 cURL 句柄添加到 cURL 批处理句柄
            curl_multi_add_handle($mh, $ch);

            // 将 cURL 句柄存储到数组中
            $ch_array[] = $ch;
        }

        // 执行所有 cURL 请求
        $running = null;
        do {
            curl_multi_exec($mh, $running);
        } while ($running > 0);


        // 获取所有请求结果
        $results = array();


        foreach ($ch_array as $ch) {
            $result = curl_multi_getcontent($ch);
            $results[] = $result;

            // 关闭 cURL 句柄
            curl_multi_remove_handle($mh, $ch);
            curl_close($ch);
        }

        // 关闭 cURL 批处理句柄
        curl_multi_close($mh);

        // 返回所有请求结果
        return $results;
    }


    public function yyToWordpresstt($info, $category, $options, $products)
    {
        // 记录程序开始时间
        $startTime = microtime(true);

        // for($i=0;$i<=20;$i++){
        //     $del_arr[] = [
        //         'url'=>'https:///?using_import_product=nNFrUJIh6gmplLMQ&action=delete',
        //         'data'=>[]
        //         ];
        //     $this->multiCurlPost($del_arr);
        // }

        // $all_sku = array_column($products,'sku');

        // // 指定每个块的大小
        // $chunk_size = 10;

        // $all_sku_list = array_chunk($all_sku, $chunk_size);

        // $success_count = 0;

        // $max_curl = 60;
        // $new_curl = 0;

        // $curl_data = [];

        // $chu_count = count($all_sku_list);

        // $is_test = false;

        // foreach ($all_sku_list as $k_chu => $chu) {


        //         if ($new_curl > $max_curl) {

        //             $curl_data[] = [
        //                 'url' => 'https:///?using_import_product=nNFrUJIh6gmplLMQ&action=add_cache_image',
        //                 'data' => [
        //                     'all_products' => base64_encode(@json_encode($chu)),
        //                     'is_test' => $k_chu
        //                 ]
        //             ];

        //             // 多curl
        //             $re_1 = $this->multiCurlPost($curl_data);


        //             $new_curl = 0;
        //             $curl_data = [];
        //         } else {
        //             $new_curl++;
        //             $curl_data[] = [
        //                 'url' => 'https:///?using_import_product=nNFrUJIh6gmplLMQ&action=add_cache_image',
        //                 'data' => [
        //                     'all_products' => base64_encode(@json_encode($chu)),
        //                     'is_test' => $k_chu
        //                 ]
        //             ];
        //         }


        //         if ($chu_count == ($k_chu + 1)) {
        //             $re_1 = $this->multiCurlPost($curl_data);
        //             $curl_data = [];

        //         }


        // }

        // halt(123);

        $images_list = DB::name('wp_images')->where('website_id', $info['id'])->select();

        $new_image_list = [];

        foreach ($images_list as $item) {


            $new_image_list[$item['sku']][] = $item['web_dir'] . '/' . $item['local_path'];

        }


        $all_cates = $category;

        // 插入商品

        $all_products = $products;


        foreach ($all_products as &$pro) {


            $images = !empty($new_image_list[$pro['sku']]) ? $new_image_list[$pro['sku']] : [];


            $pro['main_image'] = !empty($images[0]) ? $images[0] : '';

            if (!empty($images[0])) {
                unset($images[0]);
            }

            $add_attached_images = $images;


            $pro['add_attached_images'] = $add_attached_images;

            $attributes = [];

            if (!empty($pro['options'])) {

                foreach ($pro['options'] as $op) {

                    if (!empty($op['option_name']) && !empty($op['option_value_old'])) {
                        $attributes[$op['option_name']] = $op['option_value_old'];
                    }

                }

            }

            $pro['options'] = $attributes;


            if (!empty($pro['attribute_new'])) {

                $is_attribute_new = true;
                $check_price = !empty($pro['specials_price']) ? $pro['specials_price'] : $pro['price'];


                foreach ($pro['attribute_new'] as $p) {
                    if ($check_price != $p['price_use']) {
                        $is_attribute_new = false;
                        break;
                    }
                }

                if ($is_attribute_new) {
                    $pro['attribute_new'] = [];
                }

            }

        }


        // 指定每个块的大小
        $chunk_size = 10;

        $all_products_list = array_chunk($all_products, $chunk_size);


        $post_url = 'https://' . $info['domain'] . '?using_import_product=nNFrUJIh6gmplLMQ';

        $success_count = 0;

        $max_curl = 60;
        $new_curl = 0;

        $curl_data = [];

        $chu_count = count($all_products_list);

        $is_test = false;

        foreach ($all_products_list as $k_chu => $chu) {

            if ($success_count == 0) {

                $post_data = [
                    'all_cates' => base64_encode(@json_encode($all_cates)),
                    'all_products' => base64_encode(@json_encode($chu)),
                    'is_test' => $k_chu
                ];
                $re = curl_post($post_url, $post_data);


                $re = @json_decode($re, true);

                if (isset($re['code']) && $re['code'] == 1) {
                    $success_count = $success_count + $chunk_size;
                }

            } else {


                if ($new_curl > $max_curl) {

                    $curl_data[] = [
                        'url' => $post_url,
                        'data' => [
                            'all_cates' => base64_encode(@json_encode($all_cates)),
                            'all_products' => base64_encode(@json_encode($chu)),
                            'is_test' => $k_chu
                        ]
                    ];


                    // 多curl
                    $re_1 = $this->multiCurlPost($curl_data);


                    $new_curl = 0;
                    $curl_data = [];
                } else {
                    $new_curl++;
                    $curl_data[] = [
                        'url' => $post_url,
                        'data' => [
                            'all_cates' => base64_encode(@json_encode($all_cates)),
                            'all_products' => base64_encode(@json_encode($chu)),
                            'is_test' => $k_chu
                        ]
                    ];
                }


                if ($chu_count == ($k_chu + 1)) {
                    $re_1 = $this->multiCurlPost($curl_data);
                    $curl_data = [];
                }


            }
        }

        if (!empty($curl_data)) {
            $re_1 = $this->multiCurlPost($curl_data);
        }

        $all_products_count = count($all_products);

        $re = $this->checkWpImprot($info, $all_products_count);

        if (is_array($re)) {
            // 更新出错数据
            $up_list = [];

            foreach ($re as $item) {
                $pro = !empty($all_products[$item['sku']]) ? $all_products[$item['sku']] : [];
                if (!empty($pro)) {
                    $pro['wp_id'] = $item['product_id'];
                    $up_list[] = $pro;
                }
            }

            $this->updateWpData($info, $up_list, $all_cates);

        }

        $cate_new = curl_post('https://' . $info['domain'] . '?using_import_product=nNFrUJIh6gmplLMQ&action=add_menu_cate', []);


        if ($re == 'success') {
            WebModel::where('id', $info['id'])->update(['status' => 4, 'end_time' => date('Y-m-d H:i:s')]);
            echo '迁移成功';
        } else {
            WebModel::where('id', $info['id'])->update(['status' => 2, 'remark' => '商品迁移出错,重新迁移', 'end_time' => date('Y-m-d H:i:s')]);
            echo '迁移失败';
        }

        // 记录程序结束时间
        $endTime = microtime(true);
        // 计算执行时间
        $executionTime = $endTime - $startTime;
        // 输出执行时间
        echo "Script execution time: $executionTime seconds";
        die;

    }


    public function yyToWordpress($info, $category, $options, $products)
    {
        // 记录程序开始时间
        $startTime = microtime(true);

        // for($i=0;$i<=20;$i++){
        //     $del_arr[] = [
        //         'url'=>'https:///?using_import_product=nNFrUJIh6gmplLMQ&action=delete',
        //         'data'=>[]
        //         ];
        //     $this->multiCurlPost($del_arr);
        // }

        // $all_sku = array_column($products,'sku');

        // // 指定每个块的大小
        // $chunk_size = 10;

        // $all_sku_list = array_chunk($all_sku, $chunk_size);

        // $success_count = 0;

        // $max_curl = 60;
        // $new_curl = 0;

        // $curl_data = [];

        // $chu_count = count($all_sku_list);

        // $is_test = false;

        // foreach ($all_sku_list as $k_chu => $chu) {


        //         if ($new_curl > $max_curl) {

        //             $curl_data[] = [
        //                 'url' => 'https:///?using_import_product=nNFrUJIh6gmplLMQ&action=add_cache_image',
        //                 'data' => [
        //                     'all_products' => base64_encode(@json_encode($chu)),
        //                     'is_test' => $k_chu
        //                 ]
        //             ];

        //             // 多curl
        //             $re_1 = $this->multiCurlPost($curl_data);


        //             $new_curl = 0;
        //             $curl_data = [];
        //         } else {
        //             $new_curl++;
        //             $curl_data[] = [
        //                 'url' => 'https:///?using_import_product=nNFrUJIh6gmplLMQ&action=add_cache_image',
        //                 'data' => [
        //                     'all_products' => base64_encode(@json_encode($chu)),
        //                     'is_test' => $k_chu
        //                 ]
        //             ];
        //         }


        //         if ($chu_count == ($k_chu + 1)) {
        //             $re_1 = $this->multiCurlPost($curl_data);
        //             $curl_data = [];

        //         }


        // }

        // halt(123);

        $images_list = DB::name('wp_images')->where('website_id', $info['id'])->select();

        $new_image_list = [];

        foreach ($images_list as $item) {


            $new_image_list[$item['sku']][] = $item['web_dir'] . '/' . $item['local_path'];

        }


        $all_cates = $category;

        // 插入商品

        $all_products = $products;


        foreach ($all_products as &$pro) {


            $images = !empty($new_image_list[$pro['sku']]) ? $new_image_list[$pro['sku']] : [];


            $pro['main_image'] = !empty($images[0]) ? $images[0] : '';

            if (!empty($images[0])) {
                unset($images[0]);
            }

            $add_attached_images = $images;


            $pro['add_attached_images'] = $add_attached_images;

            $attributes = [];

            if (!empty($pro['options'])) {

                foreach ($pro['options'] as $op) {

                    if (!empty($op['option_name']) && !empty($op['option_value_old'])) {
                        $attributes[$op['option_name']] = $op['option_value_old'];
                    }

                }

            }

            $pro['options'] = $attributes;


            if (!empty($pro['attribute_new'])) {

                $is_attribute_new = true;
                $check_price = !empty($pro['specials_price']) ? $pro['specials_price'] : $pro['price'];


                foreach ($pro['attribute_new'] as $p) {
                    if ($check_price != $p['price_use']) {
                        $is_attribute_new = false;
                        break;
                    }
                }

                if ($is_attribute_new) {
                    $pro['attribute_new'] = [];
                }

            }

        }


        // 指定每个块的大小
        $chunk_size = 10;

        $all_products_list = array_chunk($all_products, $chunk_size);


        $post_url = 'https://' . $info['domain'] . '?using_import_product=nNFrUJIh6gmplLMQ';

        $success_count = 0;

        $max_curl = 60;
        $new_curl = 0;

        $curl_data = [];

        $chu_count = count($all_products_list);

        $is_test = false;

        foreach ($all_products_list as $k_chu => $chu) {

            if ($success_count == 0) {

                $post_data = [
                    'all_cates' => base64_encode(@json_encode($all_cates)),
                    'all_products' => base64_encode(@json_encode($chu)),
                    'is_test' => $k_chu
                ];
                $re = curl_post($post_url, $post_data);


                $re = @json_decode($re, true);

                if (isset($re['code']) && $re['code'] == 1) {
                    $success_count = $success_count + $chunk_size;
                }

            } else {


                if ($new_curl > $max_curl) {

                    $curl_data[] = [
                        'url' => $post_url,
                        'data' => [
                            'all_cates' => base64_encode(@json_encode($all_cates)),
                            'all_products' => base64_encode(@json_encode($chu)),
                            'is_test' => $k_chu
                        ]
                    ];


                    // 多curl
                    $re_1 = $this->multiCurlPost($curl_data);


                    $new_curl = 0;
                    $curl_data = [];
                } else {
                    $new_curl++;
                    $curl_data[] = [
                        'url' => $post_url,
                        'data' => [
                            'all_cates' => base64_encode(@json_encode($all_cates)),
                            'all_products' => base64_encode(@json_encode($chu)),
                            'is_test' => $k_chu
                        ]
                    ];
                }


                if ($chu_count == ($k_chu + 1)) {
                    $re_1 = $this->multiCurlPost($curl_data);
                    $curl_data = [];
                }


            }
        }

        if (!empty($curl_data)) {
            $re_1 = $this->multiCurlPost($curl_data);
        }

        $all_products_count = count($all_products);

        $re = $this->checkWpImprot($info, $all_products_count);

        if (is_array($re)) {
            // 更新出错数据
            $up_list = [];

            foreach ($re as $item) {
                $pro = !empty($all_products[$item['sku']]) ? $all_products[$item['sku']] : [];
                if (!empty($pro)) {
                    $pro['wp_id'] = $item['product_id'];
                    $up_list[] = $pro;
                }
            }

            $this->updateWpData($info, $up_list, $all_cates);

        }

        $cate_new = curl_post('https://' . $info['domain'] . '?using_import_product=nNFrUJIh6gmplLMQ&action=add_menu_cate', []);


        if ($re == 'success') {
            WebModel::where('id', $info['id'])->update(['status' => 4, 'end_time' => date('Y-m-d H:i:s')]);
            echo '迁移成功';
        } else {
            WebModel::where('id', $info['id'])->update(['status' => 2, 'remark' => '商品迁移出错,重新迁移', 'end_time' => date('Y-m-d H:i:s')]);
            echo '迁移失败';
        }

        // 记录程序结束时间
        $endTime = microtime(true);
        // 计算执行时间
        $executionTime = $endTime - $startTime;
        // 输出执行时间
        echo "Script execution time: $executionTime seconds";
        die;

    }

    // 检查wordpress导入情况
    public function checkWpImprot($info, $all_products_count)
    {
        // 检查wordpress导入情况
        $check_url = 'https://' . $info['domain'] . '?using_import_product=nNFrUJIh6gmplLMQ&action=check';

        $check_arr = curl_post($check_url, []);


        $check_arr = @json_decode($check_arr, true);

        if (empty($check_arr)) {
            return true;
        }

        $check_list_count = !empty($check_arr['all_product_check']['check_list_count']) ? $check_arr['all_product_check']['check_list_count'] : 0;

        $out_all_product = !empty($check_arr['all_product_check']['out_all_product']) ? $check_arr['all_product_check']['out_all_product'] : [];

        if (!empty($out_all_product) && ($check_list_count == $all_products_count)) {
            // 更新出错数据

            return $out_all_product;
        } else {

            return 'success';
        }


    }

    // 更新wordpress产品数据
    public function updateWpData($info, $update_data, $all_cates)
    {

        $up_url = 'https://' . $info['domain'] . '?using_import_product=nNFrUJIh6gmplLMQ&action=update';

        $chunk_size = 20;

        $update_data_list = array_chunk($update_data, $chunk_size);

        $max_curl = 20;
        $new_curl = 0;

        $curl_data = [];

        $chu_count = count($update_data_list);

        foreach ($update_data_list as $k_chu => $chu) {


            if ($new_curl > $max_curl) {
                $re_1 = $this->multiCurlPost($curl_data);

                $new_curl = 0;
                $curl_data = [];
            } else {
                $new_curl++;
                $curl_data[] = [
                    'url' => $up_url,
                    'data' => [
                        'all_cates' => base64_encode(@json_encode($all_cates)),
                        'all_products' => base64_encode(@json_encode($chu)),
                    ]
                ];
            }

            if ($chu_count == ($k_chu + 1)) {
                $re_1 = $this->multiCurlPost($curl_data);
            }


        }

        return true;

    }

    /**
     * @param $dbstr
     * @return array
     * @throws Exception
     */
    public function getCategory($dbstr): array
    {
        $category_parent_list = [];
        $categorys = Db::connect($dbstr)->table('oc_category_description cd')
            ->join('oc_category c', 'cd.category_id = c.category_id', 'LEFT')
            ->column('name,parent_id', 'c.category_id');
        foreach ($categorys as $category) {
            if (!$category['parent_id']) {
                $category_parent_list[$category['name']] = $category['category_id'];
            } else {
                $category_parent_list[$categorys[$category['parent_id']]['name'] . '/' . $category['name']] = $category['category_id'];
            }
        }
        return $category_parent_list;
    }

    /**
     * 商品分类处理
     * @param $list
     * @param $dbstr
     * @return array
     * @throws Exception
     */
    public function category($list, $dbstr): array
    {
        Db::connect($dbstr)->startTrans();
        try {
            $categoryList = $sort = [];
            foreach ($list as &$cate) {
                $title = explode('/', $cate);
                $cateItem['title'] = $cate;
                $cateItem['name'] = array_pop($title);
                $cateItem['parent_sku'] = implode("/", $title);
                $cateItem['sort'] = $sort[] = count($title);
                $categoryList[] = $cateItem;
            }
            array_multisort($sort, $categoryList);
            $category_parent_list = [];
            $category = Db::connect($dbstr)->table('category')->column('category_id', 'sku');
            foreach ($categoryList as $key => $item) {
                $parent_id = 0;
                $parent_sku = $item['name'];
                if ($item['parent_sku']) {
                    $parent_sku = $item['parent_sku'] . '/' . $item['name'];
                    $parent_id = $category_parent_list[$item['parent_sku']] ?? 0;
                }
                $insert = [
                    'name' => $item['name'],
                    'sku' => $item['title'],
                    'parent_id' => $parent_id,
                    'meta_title' => $item['name'],
                    'meta_keywords' => $item['name'],
                    'meta_description' => $item['name'],
                    'sort_order' => $key,
                    'date_added' => date('Y-m-d H:i:s')
                ];
                $category_id = $category[$item['title']] ?? 0;
                if ($category_id) {
                    Db::connect($dbstr)->table('category')->where('sku', $item['title'])->update($insert);
                } else {
                    $category_id = Db::connect($dbstr)->table('category')->insertGetId($insert);
                }
                $category_parent_list[$parent_sku] = $category_id;
            }
            Db::connect($dbstr)->commit();
            return Db::connect($dbstr)->table('category')->select();
        } catch (GuzzleException $e) {
            Db::connect($dbstr)->rollback();
            return [];
        }
    }

    /**
     * 新增商品
     * @param $list
     * @param $dbstr
     * @param $category
     * @param $db_option_name_list
     * @param $db_option_name_value
     * @param $find
     * @return bool
     * @throws Exception
     */
    public function createProducts($list, $dbstr, $category, $db_option_name_list, $db_option_name_value, $find)
    {
        // 清空商品数据
        Db::connect($dbstr)->table('product')->where('product_id', '>', 0)->delete();
        Db::connect($dbstr)->table('product_to_category')->where('product_id', '>=', 0)->delete();
        Db::connect($dbstr)->table('product_attribute')->where('product_id', '>=', 0)->delete();
        // 新增商品附图表
        Db::connect($dbstr)->execute("DROP TABLE IF EXISTS `product_to_images`;");
        Db::connect($dbstr)->execute("CREATE TABLE `product_to_images` (
               `product_id` int(11) NOT NULL,
               `image` varchar(255) NOT NULL COMMENT '图片附图'
             ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COMMENT='商品图片附图';");
        $productData = $toCategory = $toAttribute = $toImages = [];
        foreach ($list as $product) {
            $images = array_filter(explode(',', $product['images']));
            $image = $images[0] ?? '';
            $image = $this->oss_url . parse_url($image)['path'];
            $productData[] = [
                'sku' => $product['sku'],
                'name' => $product['name'],
                'short_description' => $product['short_description'],
                'description' => $product['description'],
                'meta_title' => $product['meta_title'],
                'meta_keywords' => $product['meta_keywords'],
                'meta_description' => $product['meta_description'],
                'status' => $product['status'],
                'carted' => $product['carted'],
                'master_category_id' => $category[$product['master_category']] ?? 0,
                'price' => $product['price'],
                'specials_price' => $product['specials_price'],
                'image' => $image,
                'date_added' => date('Y-m-d H:i:s')
            ];
        }

        // 添加到商品表
        if (!Db::connect($dbstr)->table('product')->limit(1000)->insertAll($productData)) {
            return false;
        }

        // $product_list = Db::connect($dbstr)->table('product')->column('product_id', 'sku');
        $product_list = $this->getProductList($dbstr);
        foreach ($list as $goods) {
            $product_id = $product_list[$goods['sku']] ?? 0;
            if ($product_id) {
                // 附图
                $images = array_filter(explode(',', $goods['images']));
                foreach ($images as $img) {
                    $toImages[] = ['product_id' => $product_id, 'image' => $this->oss_url . parse_url($img)['path']];
                }

                // 分类
                foreach ($goods['master_categorys'] as $collection) {
                    if (isset($category[(string)$collection])) {
                        $toCategory[] = ['product_id' => $product_id, 'category_id' => $category[(string)$collection]];
                    }
                }
                // 选项
                $attribute = $this->attribute($dbstr, $product_id, $goods['options'], $goods['attribute'], $db_option_name_list, $db_option_name_value, $goods['specials_price']);
                $toAttribute = array_merge($toAttribute, $attribute);
            }
        }

        // 分类
        if ($toCategory) {
            Db::connect($dbstr)->table('product_to_category')->limit(1000)->insertAll($toCategory);
        }

        // 选项
        if ($toAttribute) {
            Db::connect($dbstr)->table('product_attribute')->limit(1000)->insertAll($toAttribute);
        }

        // 商品附图
        if ($toImages) {
            Db::connect($dbstr)->table('product_to_images')->limit(1000)->insertAll($toImages);
        }
        return true;
    }

    /**
     * 商品属性值
     * @param $dbstr
     * @param $product_id
     * @param $variants
     * @param $db_option_name_list
     * @param $db_option_name_value
     * @param $price
     * @return array
     * @throws Exception
     */
    public function attribute($dbstr, $product_id, $variants, $attribute, $db_option_name_list, $db_option_name_value, $price): array
    {
        $option_price = [];
        if ($attribute) {
            $option_price = $this->getOptionPrice($attribute, $price);
        }
        $data = [];
        foreach ($variants as $var) {
            $product_option_id = $db_option_name_list[(string)$var['option_name']] ?? 0;
            $var_option_value = array_unique($var['option_value']);
            foreach ($var_option_value as $option_value) {
                $product_option_value_id = $db_option_name_value[(string)$var['option_name']][(string)$option_value] ?? 0;
                if ($product_option_id && $product_option_value_id) {
                    $add_price = $option_price[$option_value] ?? 0;
                    $price_prefix = '+';
                    if ($add_price < 0) {
                        $price_prefix = '-';
                    }
                    $data[] = [
                        'product_id' => $product_id,
                        'product_option_id' => $product_option_id,
                        'product_option_value_id' => $product_option_value_id,
                        'price' => abs($add_price),
                        'price_prefix' => $price_prefix
                    ];
                }
            }
        }
        // if ($data) {
        //     Db::connect($dbstr)->table('product_attribute')->insertAll($data);
        // }
        return $data;
    }

    public function getOptionPrice($options2, $price): array
    {
        // 判断是否是多变值选项
        $ends = [];
        foreach ($options2 as &$option) {
            $end = array_pop($option);
            $ends[] = $end;
            $option[] = $end - $price;
        }

        if (count(array_unique($ends)) < 2) {
            return [];
        }
        return $this->ax($options2);
    }


    public function ax($options): array
    {
        // try {
        $array_key_item = [];
        $count = count($options[0]);
        if ($count > 3) {
            $item = array_slice($options[0], 1, -1);
            $item_1 = implode('_', $item);
            $array_key_item[$item_1] = $item;
        } else {
            $item_1 = $options[0][1];
        }
        $array_key[(string)($options[0][0])] = 0;
        $array_key[(string)$item_1] = $options[0][$count - 1];

        array_shift($options);
        foreach ($options as $key => $option) {
            $count = count($option);
            if ($count == 2) {
                $array_key[(string)$option[0]] = end($option);
            } else {
                if ($count > 3) {
                    $item = array_slice($option, 1, -1);
                    $item_1 = implode('_', $item);
                    $array_key_item[$item_1] = $item;
                } else {
                    $item_1 = $option[1];
                }
                if (isset($array_key[(string)$option[0]])) {
                    $array_key[(string)$item_1] = end($option) - $array_key[(string)$option[0]];
                } else {
                    $array_key[(string)$option[0]] = end($option) - $array_key[(string)$item_1];
                }
            }
        }
        if ($array_key_item) {
            foreach ($array_key_item as $k => &$value) {
                $value[] = $array_key[$k];
            }
            return array_merge($array_key, $this->ax(array_values($array_key_item)));
        }
        // }catch (Exception $e){
        //     dump($e->getMessage());
        //     dump($array_key);
        //     halt($options);
        // }
        return $array_key;
    }

    /**
     * 添加图片任务
     * @param $list
     * @param $find
     * @return true
     */
    public function wp_images($list, $find): bool
    {

        $web_dir = "/www/wwwroot/{$find['domain']}/web/wp-content/uploads/images/yy";

        $images_list = DB::name('wp_images')->where('website_id', $find['id'])->column('id', 'product_id');

        foreach ($list as $product) {
            if (isset($images_list[$product['yy_id']])) {
                continue;
            }
            $path = $web_dir . "/" . $product['yy_id'];

            $pro_images = [];

            $images = explode(',', $product['images']);
            // 图片
            foreach ($images as $key => $image) {
                $extension = pathinfo(basename($images[0]), PATHINFO_EXTENSION);
                $str = '';
                if ($key > 0) {
                    $str = '_' . $key;
                }
                $img = $product['sku'] . $str . '.' . $extension;
                $pro_images[] = [
                    'website_id' => $find['id'],
                    'web_dir' => $path,
                    'product_id' => $product['yy_id'],
                    'sku' => $product['sku'],
                    'image' => $image,
                    'local_path' => $img,
                    'status' => 0,
                    'add_time' => date('Y-m-d H:i:s')
                ];
            }
            // 图片
            if ($pro_images) {
                DB::name('wp_images')->insertAll($pro_images);
            }
        }

        return true;
    }


    /**
     * 添加图片任务
     * @param $list
     * @param $find
     * @return true
     */
    public function images($list, $find): bool
    {

        $images_list = ImgModel::where('website_id', $find['id'])->column('id', 'product_id');
        // 图片
        $pro_images = [];
        foreach ($list as $product) {
            if (isset($images_list[$product['yy_id']])) {
                continue;
            }
            $images = explode(',', $product['images']);
            $images = array_filter($images);

            foreach ($images as $key => $image) {
                $pro_images[] = [
                    'website_id' => $find['id'],
                    'sku' => $product['sku'],
                    'product_id' => $product['yy_id'],
                    'yy_image' => $image,
                    'oss_image' => $this->oss_url . parse_url($image)['path'],
                    'rank' => $key,
                    'status' => 0,
                    'add_time' => date('Y-m-d H:i:s')
                ];
            }
        }

        // 图片
        if ($pro_images) {
            ImgModel::limit(1000)->insertAll($pro_images);
        }
        return true;
    }

    /**
     * 选项值
     * @param $dbstr
     * @param $options
     * @return array
     * @throws Exception
     */
    public function option($dbstr, $options): array
    {
        $db_option_name_list = Db::connect($dbstr)->table('product_option')->column('product_option_id', 'name');
        $db_option_name_value = [];
        foreach ($db_option_name_list as $db_option_name => $db_option_id) {
            $db_option_name_value[$db_option_name] = Db::connect($dbstr)->table('product_option_value')->where('product_option_id', $db_option_id)->column('product_option_value_id', 'name');
        }
        $i = 1;
        foreach ($options as $option_name => $option_values) {
            $product_option_id = $db_option_name_list[(string)$option_name] ?? 0;
            if (!$product_option_id) {
                $product_option_id = Db::connect($dbstr)->table('product_option')->insertGetId(['name' => (string)$option_name, 'sort_order' => $i]);
                $db_option_name_list[(string)$option_name] = $product_option_id;
            }
            foreach ($option_values as $value_sort => $op_name_value) {
                $product_option_value_id = $db_option_name_value[(string)$option_name][(string)$op_name_value] ?? 0;
                if (!$product_option_value_id) {
                    $product_option_value_id = Db::connect($dbstr)->table('product_option_value')->insertGetId(['name' => (string)$op_name_value, 'sort_order' => $value_sort, 'product_option_id' => $product_option_id]);
                    $db_option_name_value[(string)$option_name][(string)$op_name_value] = $product_option_value_id;
                }
            }
            $i++;
        }
        return [$db_option_name_list, $db_option_name_value];
    }

    /**
     * 本地存储图片
     * @return void
     */
    public function cope_images()
    {
        if (!config("yy_image_task")) {
            die("图片任务未开启,不执行!");
        }

        set_time_limit(0);
        ini_set('memory_limit', '1000M');
        $image_list = ImgModel::where('status', 0)->order('id')->limit(600)->select()->toArray();
        if (empty($image_list)) {
            echo '无需存储图片！';
            die;
        }
        $images_ids = array_column($image_list, 'id');
        ImgModel::where('id', 'in', $images_ids)->update(['status' => 2, 'start_time' => date("Y-m-d H:i:s")]);
        $accessKeyId = 'LTAI5tGhQ5srVvfHk3P1qhxV';
        $accessKeySecret = 'eTf45w8fV2er1djOyto4TYmABhlCiD';
        $endpoint = 'oss-us-east-1.aliyuncs.com';
        try {
            $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
        } catch (OssException $e) {
            die("OSS初始化报错: " . $e->getMessage());
        }

        $bucket = 'yiyang-yy-images';
        $thumbnail = new Thumbnail();
        $data = [];
        $files = [];

        foreach ($image_list as $image) {
            $objectName = trim(parse_url($image['yy_image'])['path'], '/');
            // 生成本地缩略图
            try {
                if ($thumbnail->get_file($image['yy_image'])) {
                    try {
                        $exists = $ossClient->doesObjectExist($bucket, $objectName);
                        if (!$exists) {
                            $res = $ossClient->uploadFile($bucket, $objectName, $thumbnail->newFile);
                            if ($res['info']['http_code'] == 200 && $res['info']['url']) {
                                $data['迁移成功'][] = $image['id'];
                            }
                        } else {
                            $data['迁移成功'][] = $image['id'];
                        }
                    } catch (OssException $e) {
                        $data['上传OSS报错' . $e->getMessage()][] = $image['id'];
                    }
                    $files[] = $thumbnail->newFile;
                } else {
                    $data['缩略图生成失败:' . $thumbnail->err][] = $image['id'];
                }
            } catch (Exception $e) {
                $data['缩略图生成失败报错' . $e->getMessage()][] = $image['id'];
            }
        }

        foreach ($data as $remark => $datum) {
            $status = $remark == '迁移成功' ? 1 : 3;
            ImgModel::where('id', 'in', $datum)->update(['status' => $status, 'end_time' => date("Y-m-d H:i:s"), 'remark' => $remark]);
        }
        $thumbnail->destroyFile($files);
        die('本地缓存完成！');
    }

    /**
     * 本地存储图片
     * @return void
     */
    public function wp_cope_images()
    {
        set_time_limit(0);
        ini_set('memory_limit', '1000M');

        $server = \app\yy\model\Server::column('web_url', 'id');
        $image_list = WebModel::alias('w')->join('wp_images i', 'w.id=i.website_id', 'right')
            ->field('i.id,i.web_dir,i.image,i.local_path,i.website_id,w.server_id')
            ->where('i.status', 0)
            ->limit(5000)
            ->order('i.id')
            ->select()
            ->toArray();

        if (empty($image_list)) {

            $img_where = [
                ['i.status', '=', 2],
                ['i.start_time', '<', date('Y-m-d H:i:s', strtotime('-5 minutes', time()))]
            ];

            $image_list = WebModel::alias('w')
                ->join('wp_images i', 'w.id=i.website_id', 'right')
                ->field('i.id,i.web_dir,i.image,i.local_path,i.website_id,w.server_id')
                ->where($img_where)
                ->limit(3000)
                ->order('i.id')
                ->select()
                ->toArray();
        }

        if (empty($image_list)) {
            echo '无需存储图片！';
            die;
        }
        $imgIds = array_column($image_list, 'id');
        DB::name('wp_images')->where('id', 'in', $imgIds)->update(['status' => 2, 'start_time' => date('Y-m-d H:i:s')]);

        $list = [];
        foreach ($image_list as $value) {
            $list[$server[$value['server_id']]][] = [
                'id' => $value['id'],
                'web_dir' => $value['web_dir'],
                'image' => $value['image'],
                'local_path' => $value['local_path']
            ];
        }

        foreach ($list as $web => $item) {
            $url = "http://{$web}/{$this->web_url}";

            $img_arr = array_chunk($item, 200);
            foreach ($img_arr as $arr) {
                $data = postUrl($url, ['token' => 'y1goj8Pbr3VzPdS', 'data' => json_encode($arr)]);


                $arrIds = array_column($arr, 'id');
                if (isset($data['code'])) {
                    foreach ($data['data'] as $status => $datum) {

                        $datum_ids = array_column($datum, 'id');

                        DB::name('wp_images')->where('id', 'in', $datum_ids)->update(['status' => $status, 'end_time' => date('Y-m-d H:i:s')]);
                    }
                } else {
                    DB::name('wp_images')->where('id', 'in', $arrIds)->update(['status' => 4, 'end_time' => date('Y-m-d H:i:s'), 'remark' => '接口返回失败']);
                }
            }
        }
        echo '本地缓存完成！';
        die;
    }


    /**
     * 网站缩略图预加载
     * @param string $id
     * @return void
     */
    public function preload_image(string $id = '')
    {
        set_time_limit(0);
        ini_set('memory_limit', '1000M');
        $bool = false;
        if ($id) {
            $info = WebModel::where('id', $id)->order('id')->find();
        } else {
            $info = WebModel::where('image_status', 2)->order('id')->find();
            if (!$info) {
                $info = WebModel::where('image_status', 1)->order('id')->find();
                $bool = true;
                if (!$info) {
                    die('无网站图片缩略图可生成');
                }
                // 网站迁移中
                WebModel::where('id', $info['id'])->update(['image_status' => 2, 'image_start' => date('Y-m-d H:i:s')]);
                // // 清除图片缓存
                // $option = array('ssl' => array('verify_peer' => false, 'verify_peer_name' => false));
                // $result = file_get_contents("https://{$info['domain']}/{$this->web_url}?token=y1goj8Pbr3VzPdS&active=clearImg", false, stream_context_create($option));
                // if ($result != 'ok'){
                //     WebModel::where('id', $info['id'])->update(['image_status' => 4, 'image_end' => date('Y-m-d H:i:s')]);
                // }
            }
        }

        $dbStr = $this->checkDb($info);
        if ($info['type'] == 0) {
            // ecshop
            (new EasyShop())->preload_image($info, $dbStr, $bool);
        } else {
            // opencart
            (new Opencart())->preload_image($info, $dbStr);
        }

        die('本地缓存完成！');
    }


    public function test($id = '')
    {
        $info = WebModel::where('id', $id)->order('id')->find();
        $dbstr = $this->checkDb($info);
        $product_list = $this->getProductList($dbstr);
        halt(count(array_unique($product_list)));

    }

    public function getProductList($dbstr, $product_id = 0)
    {
        $limit = 10000;
        $product_list = Db::connect($dbstr)->table('product')->where('product_id', '>', $product_id)->limit($limit)->column('product_id', 'sku');
        if (count($product_list) == $limit) {
            return $product_list + $this->getProductList($dbstr, max($product_list));
        } else {
            return (array)$product_list;
        }
    }

    /**
     * 读取文件信息
     * @param $file
     * @return array
     */
    public function readXlsx($file): array
    {
        $config = ['path' => './'];
        $excel = new \Vtiful\Kernel\Excel($config);
        $excel->openFile($file)
            ->openSheet();
        $key = $excel->nextRow();
        $key2 = $excel->nextRow();
        $spu = '';
        $num = 0;
        $category = $options = $products = [];
        $data = [];
        while (($row = $excel->nextRow()) !== NULL) {
            $num++;
            $val = array_combine($key, $row);
            $category = array_filter(array_flip(array_flip(array_merge($category, explode(',', $val['专辑名称'])))));
            $bool = $i = 1;
            switch ($val['商品属性*']) {
                case 'P':

                    $option_value = [];
                    $option_value_new = [];
                    do {
                        if (isset($val["款式{$i}"]) && $val["款式{$i}"] !== '') {
                            if (!in_array($val["款式{$i}"], $options[$pro_options[$i]['option_name']])) {
                                $options[$pro_options[$i]['option_name']][] = $val["款式{$i}"];
                            }
                            $products[$spu]['price'] = max($val["商品原价"], $products[$spu]['price']);
                            $products[$spu]['specials_price'] = min($val["商品售价*"], $products[$spu]['specials_price']);
                            $products[$spu]['options'][$i]['option_value_old'][] = $val["款式{$i}"];
                            $products[$spu]['options'][$i]['option_value'][] = $val["款式{$i}"];
                            $option_value[] = $val["款式{$i}"];
                            $option_value_new[$pro_options[$i]['option_name']] = $val["款式{$i}"];
                            $i++;
                        } else {
                            $option_value[] = $val["商品售价*"];
                            $option_value_new['price_use'] = $val["商品售价*"];
                            $products[$spu]['attribute'][] = $option_value;
                            $products[$spu]['attribute_new'][] = $option_value_new;
                            $bool = 0;
                        }
                    } while ($bool);
                    break;
                case 'S':
                    $value = [
                        'sku' => $val['商品spu'],
                        'yy_id' => $val['商品ID'],
                        'name' => $val['商品标题*'],
                        'description' => $val['商品描述'],
                        'short_description' => $val['简短描述'],
                        'meta_title' => $val['SEO标题'],
                        'meta_keywords' => $val['SEO关键词'],
                        'meta_description' => $val['SEO描述'],
                        'status' => $val['商品上架'] == 'Y' ? 1 : 0,
                        'carted' => 0,
                        'master_category' => explode(',', $val['专辑名称'])[0] ?? '',
                        'master_categorys' => explode(',', $val['专辑名称']),
                        'images' => $val['商品图片*'],
                        'options' => [],
                        'attribute' => [],
                        'attribute_new' => [],
                        'price' => $val['商品原价'],
                        'specials_price' => $val['商品售价*'],
                    ];
                    $products[$val['商品spu']] = $value;
                    break;
                default:
                    $spu = $val['商品spu'];
                    $pro_options = [];
                    do {
                        if (!empty($val["款式{$i}"])) {
                            $pro_options[$i]['option_name'] = $val["款式{$i}"];
                            if (!isset($options[$val["款式{$i}"]])) $options[$val["款式{$i}"]] = [];
                            $i++;
                        } else {
                            $bool = 0;
                        }
                    } while ($bool);
                    $value = [
                        'sku' => $val['商品spu'],
                        'yy_id' => $val['商品ID'],
                        'name' => $val['商品标题*'],
                        'description' => $val['商品描述'],
                        'short_description' => $val['简短描述'],
                        'meta_title' => $val['SEO标题'],
                        'meta_keywords' => $val['SEO关键词'],
                        'meta_description' => $val['SEO描述'],
                        'status' => $val['商品上架'] == 'Y' ? 1 : 0,
                        'carted' => 0,
                        'master_category' => explode(',', $val['专辑名称'])[0] ?? '',
                        'master_categorys' => explode(',', $val['专辑名称']),
                        'images' => $val['商品图片*'],
                        'options' => $pro_options,
                        'attribute' => [],
                        'attribute_new' => [],
                        'price' => '0',
                        'specials_price' => '1000',
                    ];
                    $products[$val['商品spu']] = $value;
                    break;
            }
        }
        return [$category, $options, $products];
    }

    public function flowRateTest($id = '')
    {
        set_time_limit(0);
        ini_set('memory_limit', '4000M');
        // 获取网站列表
        if ($id) {
            $list = DoModel::where('id', $id)->select();
        } else {
            $list = DoModel::where('status', 1)->select();
        }
        if (!$list) {
            die('无网站统计');
        }

        $ipService = new IpInfo();
        $ipService->test($list);
        die('请求成功');
    }

    /**
     * ip 流量统计
     * @param $id
     * @return void
     * @throws \Exception
     */
    public function flowRate($id = '')
    {
        set_time_limit(0);
        ini_set('memory_limit', '4000M');
        // 获取网站列表
        if ($id) {
            $list = DoModel::where('id', $id)->select();
        } else {
            $list = DoModel::where('status', 1)->select();
        }
        if (!$list) {
            die('无网站统计');
        }

        $ipService = new IpInfo();
        $ipService->getIPList($list);
        die('请求成功');
    }

    public function currency()
    {
        (new Currency())->index();
        die('请求成功');
    }


    /**
     * 订单统计
     * @return void
     */
    public function getOrderList($id = '')
    {
        set_time_limit(0);
        ini_set('memory_limit', '4000M');
        // 获取网站列表
        if ($id) {
            $list = DoModel::where('id', $id)->select();
        } else {
            $list = DoModel::where('status', 1)->select();
        }
        if (!$list) {
            die('无网站统计');
        }
        $orderService = new \app\yy\services\Order();
        $orderService->getOrderList($list);

        die('订单同步成功');
    }

}